package current_limiting

import (
	"fmt"
	"golang.org/x/time/rate"
	"sync"
	"time"
)

func LimitHandle() {
	// 初始化限流器
	l := rate.NewLimiter(5, 10)
	//ctx := context.Background()
	start := time.Now()
	// 处理二十个请求
	for i := 0; i < 20; i++ {
		// 消费方式1
		//// 消费token，如果令牌桶内个数小于1个，则阻塞，token大于1，则继续还行后续逻辑
		//// 注意：设置n时候，如果小于限流器的容量，系统会提示等待数量超过限流器的容量
		//err := l.WaitN(ctx, 2)
		//if err != nil {
		//	fmt.Printf("触发限流，等待中 => [%+v]", err)
		//}

		// 消费方式2
		// 如果没有令牌，则直接返回false
		if l.Allow() {
			fmt.Println("处理请求：", i, time.Now().Format("2006-01-02 03:04:05"), time.Now().UnixNano()/1e6)
		} else {
			fmt.Println("无令牌，丢弃请求")
		}
	}
	fmt.Println(time.Since(start))
}

func CounterLimit() {
	secondMaxCount := 4
	counterMap := sync.Map{}
	for i := 1; i <= 20; i++ {
		var count int
		if i == 10 {
			time.Sleep(time.Millisecond * 1000)
		}
		mapValue, ok := counterMap.Load(time.Now().Unix())
		if ok {
			count = mapValue.(int)
		}
		if count >= secondMaxCount {
			fmt.Println("触发限流措施，丢弃请求", i, time.Now().Format("2006-01-02 03:04:05"), time.Now().UnixNano()/1e6)
			continue
		}
		fmt.Println("处理请求：", i, time.Now().Format("2006-01-02 03:04:05"), time.Now().UnixNano()/1e6)
		counterMap.Store(time.Now().Unix(), count+1)
		time.Sleep(time.Millisecond * 10)
	}
}
